﻿using System;
using System.Collections.Generic;

namespace UniSender
{
    /// <summary>
    /// Базовый класс исключения
    /// </summary>
    public class UniSenderException : Exception
    {
        protected bool isDataSerialized = false;

        /// <summary>
        /// Язык
        /// </summary>
        public string Lang { get; set; }

        /// <summary>
        /// Метод
        /// </summary>
        public string Method { get; set; }

        /// <summary>
        /// Параметры
        /// </summary>
        public IDictionary<string, object> Args { get; set; }

        /// <summary>
        /// Инициализация исключения
        /// </summary>
        /// <param name="message">Описание ошибки</param>
        /// <param name="innerException">Исключение, которое послужило причиной</param>
        public UniSenderException(string message, Exception innerException)
            : base(message, innerException)
        { }

        /// <summary>
        /// Инициализация исключения
        /// </summary>
        /// <param name="message">Описание ошибки</param>
        public UniSenderException(string message)
            : base(message)
        { }

        /// <summary>
        /// Инициализация исключения
        /// </summary>
        public UniSenderException()
            : base()
        { }

        /// <summary>
        /// Gets a collection of key/value pairs that provide additional user-defined information about the exception.
        /// </summary>
        public override System.Collections.IDictionary Data
        {
            get
            {
                if (!isDataSerialized)
                {
                    isDataSerialized = true;
                    SerializeData();
                }
                return base.Data;
            }
        }

        protected virtual void SerializeData()
        {
            Data.Add("UniSender_Lang", Lang);
            Data.Add("UniSender_Method", Method);
            Data.Add("UniSender_Args", Args);
        }
    }

    /// <summary>
    /// Ошибка при формировании или выполнении запроса к серверу
    /// </summary>
    public class UniSenderTransportException : UniSenderException
    {
        /// <summary>
        /// Ключ клиента
        /// </summary>
        public string Key { get; set; }

        /// <summary>
        /// Метод запроса
        /// </summary>
        public string HttpMethod { get; set; }

        /// <summary>
        /// Сформированный URL запроса к серверу
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        /// Тело запроса методом POST
        /// </summary>
        public string Query { get; set; }

        /// <summary>
        /// Инициализация исключения
        /// </summary>
        /// <param name="message">Описание ошибки</param>
        /// <param name="innerException">Исключение, которое послужило причиной</param>
        public UniSenderTransportException(string message, Exception innerException)
            : base(message, innerException)
        { }

        protected override void SerializeData()
        {
            base.SerializeData();
            Data.Add("UniSender_Key", Key);
            Data.Add("UniSender_Url", Url);
        }
    }

    /// <summary>
    /// Ошибка при разборе ответа сервера
    /// </summary>
    public class UniSenderParseException : UniSenderException
    {
        /// <summary>
        /// Текст ответа сервера
        /// </summary>
        public string ResponseText { get; set; }

        /// <summary>
        /// Ожидаемый тип результата
        /// </summary>
        public Type ExpectedType { get; set; }

        /// <summary>
        /// Инициализация исключения
        /// </summary>
        /// <param name="message">Описание ошибки</param>
        /// <param name="innerException">Исключение, которое послужило причиной</param>
        public UniSenderParseException(string message, Exception innerException)
            : base(message, innerException)
        { }

        protected override void SerializeData()
        {
            base.SerializeData();
            Data.Add("UniSender_Response", ResponseText);
            Data.Add("UniSender_ExpectedType", ExpectedType);
        }
    }

    /// <summary>
    /// Ошибка, которую вернул сервис
    /// </summary>
    public class UniSenderErrorException : UniSenderException
    {
        /// <summary>
        /// Код ошибки
        /// </summary>
        public string Code { get; set; }

        /// <summary>
        /// Описание ошибки
        /// </summary>
        public string Error { get; set; }

        /// <summary>
        /// Инициализация исключения
        /// </summary>
        /// <param name="message">Описание ошибки</param>
        public UniSenderErrorException(string message)
            : base(message)
        { }

        protected override void SerializeData()
        {
            base.SerializeData();
            Data.Add("UniSender_Error", Error);
            Data.Add("UniSender_Code", Code);
        }
    }
}
